﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ZedGraph
{
    public partial class MainForm : Form
    {
        private GraphPane myPane = new GraphPane();
        private int listCount;
        private PointPairList list1 = new PointPairList();
        //private GraphPane Proections = new GraphPane();
      //  private List<LineItem> curves = new List<LineItem>();
        //Form AboutForm = new Form();
        public MainForm()
        {
            InitializeComponent();
            zedGraphControl1.ContextMenuBuilder += new ZedGraphControl.ContextMenuBuilderEventHandler(zedGraphControl1_ContextMenuBuilder);
        }
        
        void zedGraphControl1_ContextMenuBuilder(ZedGraphControl sender, ContextMenuStrip menuStrip, Point mousePt, ZedGraphControl.ContextMenuObjectState objState)
        {
            // !!! 
            // Переименуем (переведем на русский язык) некоторые пункты контекстного меню
           menuStrip.Items[0].Text = "Копировать";
            menuStrip.Items[1].Text = "Сохранить как картинку…";
            menuStrip.Items[2].Text = "Параметры страницы…";
            menuStrip.Items[3].Text = "Печать…";
           menuStrip.Items[4].Text = "Показывать значения в точках…";
            menuStrip.Items[7].Text = "Установить масштаб по умолчанию…";
            
            // Некоторые пункты удалим
            menuStrip.Items.RemoveAt(5);
           menuStrip.Items.RemoveAt(5);

            
        }
       
        private void GraphCreate_Click(object sender, EventArgs e)
        {
            //curves.Clear();
            
            CreateGraph(zedGraphControl1,new Point(0,0)); // строим график
            SetSize(); // и устанавливаем его положение и размер
            zedGraphControl1.Refresh();
            
        }
        private void Form1_Resize(object sender, EventArgs e)
        {
            SetSize();
        }
        private void SetSize()
        {
            zedGraphControl1.Location = new Point(15, 15); // задаем положение графика
            zedGraphControl1.Size = new Size(ClientRectangle.Width - 375, ClientRectangle.Height - 75); // размеры графика

        }
        private void CreateGraph(ZedGraphControl zgc, PointF mousePoint)
        {
            
            GraphPane myPane = zgc.GraphPane;
            myPane.CurveList.Clear();
            list1.Clear();
            // Задаем название графика и сторон
            myPane.Title.Text = "График";
            myPane.XAxis.Title.Text = "Доза";
            myPane.YAxis.Title.Text = "Число погибших животных";
            // --------------------------------
            // строим график
            
            
            double x, y;
            
            List<LineItem> curves = new List<LineItem>();
            foreach (DataGridViewRow row in dataGridView1.Rows)
            {
                x = Convert.ToDouble(row.Cells[0].Value);
                y = Convert.ToDouble(row.Cells[1].Value);
                list1.Add(x, y);
            }
           
            curves.Add(new LineItem("График", list1, Color.Red, SymbolType.Diamond));
           
            foreach (DataGridViewRow row in dataGridView1.Rows)
            {
             var cell = row.Cells[2] as DataGridViewCheckBoxCell;
                if (Convert.ToBoolean(cell.Value) == true)
                {
                PointPairList listx = new PointPairList();
                x = Convert.ToDouble(row.Cells[0].Value);
                y = Convert.ToDouble(row.Cells[1].Value);
                listx.Add(0,y);
                listx.Add(x, y);
                listx.Add(x, 0);
                curves.Add(new LineItem("", listx, Color.Blue, SymbolType.Diamond)); 
                }
            }

            PointPairList listProections = new PointPairList();

            // Пересчитываем пиксели в координаты на графике
            // У ZedGraph есть несколько перегруженных методов ReverseTransform.
           
            listProections.Add(0, mousePoint.Y);
            listProections.Add(mousePoint.X, mousePoint.Y);
            listProections.Add(mousePoint.X, 0);
            curves.Add(new LineItem("График проекции", listProections, Color.Blue, SymbolType.Diamond));
            // Выводим результат
            listCount = list1.Count;
            PointPairList list2 = new PointPairList();
            list2.Add(list1[listCount - 1].X, list1[listCount - 1].Y);
            if (radioButton1.Checked && listCount>=2)
            {
                x = (-(list1[listCount - 1].X - list1[listCount - 2].X) * Convert.ToInt32(numericUpDown2.Value) -
                    (list1[listCount - 2].X * list1[listCount - 1].Y - list1[listCount - 1].X * list1[listCount - 2].Y)) /
                    (list1[listCount - 2].Y - list1[listCount - 1].Y);
                list2.Add(x, Convert.ToInt32(numericUpDown2.Value));
                curves.Add(new LineItem("График линейной аппроксимации", list2, Color.DarkGreen, SymbolType.Diamond, 2));
            }
            bool isGraphLabelVisible = true;
            int i = 0;
            foreach (LineItem u in curves)
            {
                u.Label.IsVisible = isGraphLabelVisible;
                myPane.CurveList.Add(u);
                i++;
            }
            SafeLine.Text = "";
            BitDeadyLine.Text = "";
            DedyLine.Text = "";
            zgc.AxisChange();
        }




        private void xyAxis(ZedGraphControl zgc)
        {
            myPane = zgc.GraphPane;
            myPane.XAxis.MajorGrid.IsVisible = true;
            myPane.XAxis.MajorGrid.DashOn = 10;
            myPane.XAxis.MajorGrid.DashOff = 5;
            myPane.YAxis.MajorGrid.IsVisible = true;
            myPane.YAxis.MajorGrid.DashOn = 10;
            myPane.YAxis.MajorGrid.DashOff = 5;
            myPane.YAxis.MinorGrid.IsVisible = true;
            myPane.YAxis.MinorGrid.DashOn = 1;
            myPane.YAxis.MinorGrid.DashOff = 2;
            myPane.XAxis.MinorGrid.IsVisible = true;
            myPane.XAxis.MinorGrid.DashOn = 1;
            myPane.XAxis.MinorGrid.DashOff = 2;
        }
        private void numericUpDown1_ValueChanged(object sender, EventArgs e)
        {
            GraphCreate.Enabled = false;
            int colCount = Convert.ToInt32(numericUpDown1.Value);
            dataGridView1.RowCount = colCount;
            DataGridViewRow row = dataGridView1.Rows[colCount - 1];
            row.Cells[0].Value = 0.0;
            row.Cells[1].Value = 0.0;
            if (numericUpDown1.Value != 1)
            {
                GraphCreate.Enabled = true;
            }
        }

    
        private void Form1_Load(object sender, EventArgs e)
        {
            GraphCreate.Enabled = false;
            numericUpDown1_ValueChanged(null, null);
            xyAxis(zedGraphControl1);
        }
        private void dataGridView1_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
        {
            int newInteger;
           if(dataGridView1.CurrentCell.ColumnIndex == 1)
           {
               if (int.TryParse(e.FormattedValue.ToString(), out newInteger) && newInteger > Convert.ToInt32(numericUpDown2.Value))
               {
                   e.Cancel = true;
                   MessageBox.Show("Неверные данные, количество животных не должно превышать их максимального значения");
               }
           }
           
            
            dataGridView1.Rows[e.RowIndex].ErrorText = "";
            double newDouble;
           if (dataGridView1.Columns[e.ColumnIndex].Name == "cheak")
           {
                return;
            }
            if (dataGridView1.Rows[e.RowIndex].IsNewRow) { return; }
            if (!double.TryParse(e.FormattedValue.ToString(),
                out newDouble) || newDouble < 0)
            {
                e.Cancel = true;
           MessageBox.Show("the value must be a non-negative integer");
            }
        }

        private void сохранитьКартинкуКакToolStripMenuItem_Click(object sender, EventArgs e)
        {
            zedGraphControl1.SaveAsBitmap();
        }

        private void выходToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void копироватьРисунокToolStripMenuItem_Click(object sender, EventArgs e)
        {
            bool isShowmessage = false;
           zedGraphControl1.Copy(isShowmessage);
        }

        private void параметрыСтраницыToolStripMenuItem_Click(object sender, EventArgs e)
        {
            zedGraphControl1.DoPageSetup();
        }

        private void установитьМасштабПоУмолчаниюToolStripMenuItem_Click(object sender, EventArgs e)
        {
            zedGraphControl1.ZoomOutAll(myPane);
        }

        private void печатьToolStripMenuItem_Click(object sender, EventArgs e)
        {
            zedGraphControl1.DoPrint();
        }

        private void оПрограммеToolStripMenuItem_Click(object sender, EventArgs e)
        {
            aboutForm AboutForm = new aboutForm();
            AboutForm.ShowDialog();
        }
     
        private bool zedGraphControl1_MouseMoveEvent(ZedGraphControl sender, MouseEventArgs e)
        {
        // Сюда будут записаны координаты в системе координат графика

            if (myPane.CurveList.Count > 0 ||  (myPane.CurveList.Count == 2  &&  myPane.CurveList[0].Points[0].X == 0 && myPane.CurveList[0].Points[0].Y == 0))
            {
                
                
                    double x, y;
                DataGridViewRow row = null;
        zedGraphControl1.GraphPane.ReverseTransform(e.Location, out x, out y);
        
                    CreateGraph(zedGraphControl1,new PointF((float)x,(float)y));
            string text = string.Format("Доза препарата: {0} мг/кг; Число погибших животных: {1}", Math.Round(x,3) , (int)y);
            coardlabel.Text = text;
            //zedGraphControl1.RestoreScale(myPane);
            zedGraphControl1.Invalidate();
                
           }
        
            return true;
        }

        private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            
        }

        private void CreateGraphregress(ZedGraphControl zgc, PointF mousePoint)
    {
          double YS, XS, St, Sb, b0, b1;
            double x, y;
            GraphPane myPane = zgc.GraphPane;
            List<LineItem> curves = new List<LineItem>();
            PointPairList regress = new PointPairList();
            regress.Clear();
            list1.Clear();
            //myPane.CurveList.Clear();
            // Задаем название графика и сторон
            myPane.Title.Text = "График";
            myPane.XAxis.Title.Text = "Доза";
            myPane.YAxis.Title.Text = "Число погибших животных";
            // --------------------------------
            // строим график
            
            
            
            
            
            foreach (DataGridViewRow row in dataGridView1.Rows)
            {
                x = Convert.ToDouble(row.Cells[0].Value);
                y = Convert.ToDouble(row.Cells[1].Value);
                list1.Add(x, y);
            }
            listCount = list1.Count;
            double[] YR = new double[listCount];
            YS = 0;
            XS = 0;
            for (int i = 0; i < listCount; i++)
            {
                YS += list1[i].Y;
                XS += list1[i].X;
            }
            YS = YS / listCount;
            XS = XS / listCount;
            St = 0;
            Sb = 0;
            for (int i = 0; i < listCount; i++)
            {
                St += (list1[i].X - XS) * (list1[i].Y - YS);
                Sb += (list1[i].X - XS) * (list1[i].X - XS);
            }
            b1 = St / Sb;
            b0 = YS - b1 * XS;
            for (int i = 0; i < listCount; i++)
            {
                YR[i] = b0 + b1 * list1[i].X;
            }
            
            for (int i = 0; i < listCount; i++)
            {
               regress.Add(list1[i].X, YR[i]);
            }
            curves.Add(new LineItem("График регрессии", regress, Color.DarkMagenta, SymbolType.Diamond,2));
                 myPane.CurveList.Add(curves[0]);
            
           
            zgc.AxisChange();
    }

        private void button1_Click(object sender, EventArgs e)
        {
            CreateGraphregress(zedGraphControl1,new Point(0,0)); // строим график
            SetSize(); // и устанавливаем его положение и размер
            zedGraphControl1.Refresh();
        }

      
       
    

       
    }
}
